package ch.elca.lol.puissance4.board;

import ch.elca.lol.puissance4.game.Token;

// TODO we may get better performance if we remove the interface and use the class directly
// TODO add exception management in the interface

/** Interface for game boards, expected to be immutable. */
public interface Board {
	abstract public Board play(int col, Token t);
	
	/** Returns true iff the given coordinate is inside the board. */
	public abstract boolean isInBounds(int x, int y);
	
	/** Returns true iff the space at [x,y] has no token. */
	public abstract boolean isEmpty(int x, int y);
	
	/** Returns true iff a token can be inserted at the given column. */
	public abstract boolean isPlayable(int col);
	
	/** Returns the width of the board. */
	public abstract int getWidth();
	
	/** Returns the height of the board. */
	public abstract int getHeight();
	
	/** Returns the token at the given coordinate. Returns null if the coordinate is out of the board. */
	public abstract Token get(int x, int y);
	
	/** Returns the token at the given coordinate. Behavior is undefined if the coordinate is out of the board. */
	public abstract Token unsafeGet(int x, int y);
	
	/** Returns true if any player has won, or the game board is full. */
	public abstract boolean isGameOver();
	
	/** Returns true iff the player designated by the given token has won the game. */
	public abstract boolean hasWon(Token player);
	
	/** Returns the Token of the winner if there's one, or null if the game isn't finished or is a stalemate. */
	public abstract Token getWinner();
	
	/** Prints the board as a matrix of characters, X and O for played squares and . for empty ones. */
	@Override
	public abstract String toString();
	
	/** Returns the column index at which the last move was played, or -1 if no move has been played yet. */
	public abstract int getLastMove();

	/** Returns the number of tokens on the given column*/
	public abstract int getColumnHeight(int col);
}